/*
 * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

use crate::cli::ZipArgs;
use crate::zip::ZipArchive;
use anyhow::Result;

pub fn execute(args: &ZipArgs) -> Result<()> {
    log::info!("Starting list operation...");

    let zipfile = args.zipfile.as_deref().unwrap().to_str().unwrap();

    let archive = ZipArchive::new(zipfile)?;

    let escape = matches!(args.other.encode.as_deref(), Some("Escape"));
    let all_entries = archive.file_names();

    println!("Archive contains:");
    for entry in all_entries {
        if !escape {
            println!("  {}", entry);
            continue;
        }
        let escaped = escape_unicode(&entry);
        if args.show.show_unicode_only {
            println!("  {}", escaped);
        } else if args.show.show_unicode {
            println!("  {}", escaped);
            if entry != escaped {
                println!("    Escaped Unicode:  {}", escaped);
            }
        } else {
            println!("  {}", entry);
        }
    }
    println!(
        "Total {} entries ({} bytes)",
        archive.len(),
        archive.get_total_original_size()
    );

    Ok(())
}

// Unicode转义辅助函数
fn escape_unicode(name: &str) -> String {
    let mut escaped = String::new();
    for c in name.chars() {
        if !c.is_ascii() {
            let code = c as u32;
            if code <= 0xFFFF {
                escaped.push_str(&format!("#U{:04X}", code));
            } else {
                escaped.push_str(&format!("#L{:06X}", code));
            }
        } else {
            escaped.push(c);
        }
    }
    escaped
}
